package com.xxl.job.executor.service.jobhandler;

import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobContext;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.executor.mybatis.service.JobUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.*;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.job.builder.FlowBuilder;
import org.springframework.batch.core.job.flow.Flow;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.Date;

import static com.xxl.job.core.handler.IJobHandler.SUCCESS;

/**
 * @author: 吴多强
 * @description:
 **/
@Configuration
@EnableBatchProcessing
public class ShardingSpringBatchFlow {

    private static Logger logger = LoggerFactory.getLogger(ShardingSpringBatchFlow.class);
    @Resource
    private JobUserService jobUserService;

    @Autowired
    private JobLauncher jobLauncher;

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    private int index, total, all, avg;

    @XxlJob("ShardingSpringBatchFlow")
    public ReturnT<String> shardingJobHandler(String param) throws Exception {
        // 当前分片序号
        index = XxlJobContext.getXxlJobContext().getShardIndex() + 1;
        // 总分片数
        total = XxlJobContext.getXxlJobContext().getShardTotal();
        // 总的分片任务
        all = Integer.parseInt(param);
        // 平均分片个数
        avg = all / total;
        logger.info("当前分片序号" + index + "总分片数" + total + "总的分片任务" + all + "平均分片个数" + avg);
        JobParameters jobParameters = new JobParametersBuilder().addDate("date", new Date())
                .toJobParameters();
        jobLauncher.run(flowJob(), jobParameters);
        return SUCCESS;
    }

    public Job flowJob() {
        return jobBuilderFactory.get("flowJob")
                .start(flow1())
                .next(flow2())
                .end()
                .build();
    }

    public Step flowStep1() {
        return stepBuilderFactory.get("flowStep1").tasklet(new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                logger.info("业务逻辑1");
                return RepeatStatus.FINISHED;
            }
        }).build();
    }

    public Step flowStep2() {
        return stepBuilderFactory.get("flowStep2").tasklet(new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                logger.info("业务逻辑2");
                return RepeatStatus.FINISHED;
            }
        }).build();
    }

    public Step flowStep3() {
        return stepBuilderFactory.get("flowStep3").tasklet(new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                logger.info("业务逻辑3");
                return RepeatStatus.FINISHED;
            }
        }).build();
    }

    /**
     * 一个Flow可以包含多个Step
     *
     * @return
     */
    public Flow flow1() {
        return new FlowBuilder<Flow>("flow1")
                .start(flowStep1())
                .next(flowStep2())
                .build();
    }

    public Flow flow2() {
        return new FlowBuilder<Flow>("flow2")
                .start(flowStep3())
                .build();
    }
}
